/** !A gui list object
This module contains a list object containing a number of selectable elements
and a scrollable area. */

#ifndef MX_DEPUI_LIST_HEADER
#   define MX_DEPUI_LIST_HEADER

#   include "depui/depui.h"

#   ifdef __cplusplus
extern "C" {
#   endif
	typedef struct MX_LISTELEM_DATA {
		union {
			MX_BUTTON_DATA button;
			MX_TEXTUAL_DATA textual;
			MX_OBJ_DATA obj;
			MX_RECTATOM_DATA rectatom;
			MX_ATOM atom;
		} base;
		 MX_DLLIST_NODE(struct MX_LISTELEM_DATA, struct MX_LIST_DATA);
	} MX_LISTELEM_DATA;

/** !A list element type */
	typedef struct MX_LISTELEM {
		union {
			MX_LISTELEM_DATA listelem;
			MX_BUTTON_DATA button;
			MX_TEXTUAL_DATA textual;
			MX_OBJ_DATA obj;
			MX_RECTATOM_DATA rectatom;
			MX_ATOM atom;
		} base;
	} MX_LISTELEM;

/**type_conversion
!Convert to MX_LISTELEM base object */
#   define MXLISTELEM(o)   (&(o)->base.listelem)

/**class !Class function for MX_LISTELEM */
	void mx_listelem_class(void);

	MX_LISTELEM *mx__listelem(MX_LISTELEM_DATA * listelem, size_t size, struct MX_LIST_DATA *parent, int id);

/** !Construct a list element */
#   define mx_listelem(l,s,p,i) mx__listelem(MXLISTELEM(l),(s),MXLIST(p),(i))

	typedef struct MX_LIST_DATA {
		union {
			MX_SCROLL_DATA scroll;
			MX_OBJ_DATA obj;
			MX_RECTATOM_DATA rectatom;
			MX_ATOM atom;
		} base;
		 MX_DLLIST_ELEM(MX_LISTELEM_DATA);
		 MX_BITFIELD(_multiple);
		 MX_BITFIELD(_changeing);
	} MX_LIST_DATA;

/** !A scrollable list object
This object contains a number of selecteable elements in a (if necessary)
scrollable area. */
	typedef struct MX_LIST {
		union {
			MX_LIST_DATA list;
			MX_SCROLL_DATA scroll;
			MX_OBJ_DATA obj;
			MX_RECTATOM_DATA rectatom;
			MX_ATOM atom;
		} base;
	} MX_LIST;

/**type_conversion
!Convert to MX_LIST base class */
#   define MXLIST(o)   (&(o)->base.list)

/**class !Class function for MX_LIST */
	void mx_list_class(void);

	MX_LIST *mx__list(MX_LIST_DATA * list, size_t size, MX_OBJ_DATA * parent, int id);

/** !Create a MX_LIST object */
#   define mx_list(m,s,p,i) mx__list(MXLIST(m),(s),MXOBJ(p),(i))

	MX_LISTELEM *mx__list_append(MX_LIST_DATA * list, const char *text, int len, MX_FREE dfree, int id);

/** !Append list element from text */
#   define mx_list_append(l,t,le,f,id) mx__list_append(MXLIST(l),(t),(le),(f),(id))

	void mx__list_multiple(MX_LIST_DATA * list, const unsigned multi);

/** !Determine if a list allows multiple selected items */
#   define mx_list_multiple(l,m) mx__list_multiple(MXLIST(l),(m))

	void mx__list_select_id(MX_LIST_DATA * list, int id, unsigned doit);

/** !Select list elements with a given ID number */
#   define mx_list_select_id(l,i,d) mx__list_select_id(MXLIST(l),(i),(d))

	MX_LISTELEM *mx__list_selected(MX_LIST_DATA * list, MX_LISTELEM_DATA * ptr);

/** !Return first selection in list */
#   define mx_list_selected(l,p) mx__list_selected(MXLIST(l),MXLISTELEM(p))

	int mx__list_selected_id(MX_LIST_DATA * list);

/** !Return the ID number of the first selection */
#   define mx_list_selected_id(l) mx__list_selected_id(MXLIST(l))

	MX_LISTELEM *mx__list_first(MX_LIST_DATA * list);

/** !Return the first list element */
#   define mx_list_first(l) mx__list_first(MXLIST(l))

	MX_LISTELEM *mx__list_last(MX_LIST_DATA * list);

/** !Return the last list element */
#   define mx_list_last(l) mx__list_last(MXLIST(l))

	void mx__list_empty(MX_LIST_DATA * list);

/** !Remove all list elements */
#   define mx_list_empty(l) mx__list_empty(MXLIST(l))

	MX_LISTELEM *mx__list_next(MX_LISTELEM_DATA * listelem);

/** !Return the following list element */
#   define mx_list_next(l) mx__list_next(MXLISTELEM(l))

	MX_LISTELEM *mx__list_prev(MX_LISTELEM_DATA * listelem);

/** !Return the previous list element */
#   define mx_list_prev(l) mx__list_prev(MXLISTELEM(l))

#   ifdef __cplusplus
}
#   endif
#endif
